package com.whfc.ms.api.hdc.service.impl;

import com.whfc.common.exception.BizException;
import com.whfc.common.file.FileHandler;
import com.whfc.common.file.FilePathConfig;
import com.whfc.common.push.*;
import com.whfc.common.result.PageData;
import com.whfc.common.result.ResultEnum;
import com.whfc.common.util.RandomUtil;
import com.whfc.hdc.dto.FshDeviceDataDTO;
import com.whfc.hdc.dto.FshDeviceMediaDTO;
import com.whfc.hdc.dto.FshStrRoomIdDTO;
import com.whfc.hdc.enums.*;
import com.whfc.hdc.params.FshDeviceControlParam;
import com.whfc.hdc.params.FshDeviceInitParam;
import com.whfc.hdc.params.FshDeviceMediaParam;
import com.whfc.hdc.params.FshEnterRoomParam;
import com.whfc.hdc.service.FshDeviceConfigService;
import com.whfc.hdc.service.FshDeviceDataService;
import com.whfc.hdc.service.FshDeviceMediaService;
import com.whfc.ms.api.hdc.service.MsFshService;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.*;

/**
 * @author qzexing
 * @version 1.0
 * @date 2021-04-09 15:19
 */
@Service
public class MsFshServiceImpl implements MsFshService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private JpushProperties jpushProps;

    @Autowired
    private FilePathConfig filePathConfig;

    @Autowired
    private FileHandler fileHandler;

    @DubboReference(interfaceClass = FshDeviceConfigService.class, version = "1.0.0")
    private FshDeviceConfigService deviceConfigService;

    @DubboReference(interfaceClass = FshDeviceDataService.class, version = "1.0.0")
    private FshDeviceDataService fshDeviceDataService;

    @DubboReference(interfaceClass = FshDeviceMediaService.class, version = "1.0.0")
    private FshDeviceMediaService fshDeviceMediaService;

    @Override
    public PageData<FshDeviceDataDTO> list(Integer pageNum, Integer pageSize, String keyword) {
        return fshDeviceDataService.list(pageNum, pageSize, keyword);
    }

    @Override
    public void control(FshDeviceControlParam params) {
        List<String> registrationIdList = deviceConfigService.getRegistrationIdList(Collections.singletonList(params.getSn()));
        if (registrationIdList.isEmpty()) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "该设备尚未注册");
        }
        Map<String, String> extras = new HashMap<>();
        FshControlType controlType = FshControlType.parseValue(params.getControlType());
        if (controlType == null) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "控制类型错误");
        }
        String title = "";
        String content = "";
        if (FshControlType.BROADCAST.equals(controlType)) {
            //广播
            String broadcast = params.getBroadcast();
            if (StringUtils.isBlank(broadcast)) {
                throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "广播内容不能为空");
            }
            title = "广播";
            content = "发起广播";
            extras.put("broadcast", broadcast);
        } else if (FshControlType.LIGHT.equals(controlType)) {
            //照明
            FshLight fshLight = FshLight.parseValue(params.getLight());
            if (fshLight == null) {
                throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "照明开关不能为空");
            }
            title = "照明";
            content = "照明开关";
            extras.put("light", fshLight.getValue().toString());
        } else if (FshControlType.VOICE.equals(controlType)) {
            //语音
            title = "语音通话";
            content = "语音通话";
            extras.put("strRoomId", params.getSn());
            extras.put("type", FshCallType.VOICE.getValue().toString());
        } else if (FshControlType.VIDEO.equals(controlType)) {
            //视频
            title = "视频通话";
            content = "视频通话";
            extras.put("strRoomId", params.getSn());
            extras.put("type", FshCallType.VIDEO.getValue().toString());
        }
        if (extras.isEmpty()) {
            return;
        }
        //推送消息
        JPushApi jPushApi = new JPushApi(jpushProps.getAppKey(), jpushProps.getMasterSecret(), jpushProps.getApnsProduction(), JPushPlatform.ANDROID, JPushType.MESSAGE);
        JPushMessage message = new JPushMessage();
        message.setTitle(title);
        message.setContent(content);
        message.setExtras(extras);
        jPushApi.pushToDevices(registrationIdList, message);
    }

    @Override
    public PageData<FshDeviceDataDTO> getDataLog(String sn, Integer pageNum, Integer pageSize, Date startTime, Date endTime) {
        return fshDeviceDataService.getDataLog(sn, pageNum, pageSize, startTime, endTime);
    }

    @Override
    public PageData<FshDeviceMediaDTO> getMediaList(String sn, Integer pageNum, Integer pageSize, Date startTime,
                                                    Date endTime, List<Integer> mediaTypes, List<Integer> sources) {
        return fshDeviceMediaService.list(sn, pageNum, pageSize, startTime, endTime, mediaTypes, sources);
    }

    @Override
    public void upload(String sn, Integer mediaType, MultipartFile file) {
        //上传文件
        FshMediaType type = FshMediaType.parseValue(mediaType);
        if (type == null) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "文件类型不存在");
        }

        //保存文件
        String filename = file.getOriginalFilename();
        String suffix = "";
        if (StringUtils.isNotBlank(filename)) {
            suffix = filename.substring(filename.lastIndexOf("."));
        }
        String filePath = filePathConfig.getFilePath("hdc/fsh/file");
        String fileName = RandomUtil.getRandomFileName() + suffix;
        String fileUrl;
        try {
            //文件上传
            InputStream inputStream = file.getInputStream();
            fileUrl = fileHandler.upload(filePath + "/" + fileName, inputStream);
        } catch (Exception e) {
            logger.warn("视频安全帽上传文件失败", e);
            return;
        }

        //保存记录
        if (fileUrl == null) {
            return;
        }
        FshDeviceMediaParam param = new FshDeviceMediaParam();
        param.setSn(sn);
        param.setMediaType(mediaType);
        param.setFileUrl(fileUrl);
        param.setSource(FshMediaSource.WEB.getValue());
        fshDeviceMediaService.addDeviceMedia(param);
    }

    @Override
    public void initDeviceConfig(FshDeviceInitParam params) {
        deviceConfigService.initDeviceConfig(params);
    }

    @Override
    public FshStrRoomIdDTO enterRoom(FshEnterRoomParam params) {
        List<String> snList = params.getSnList();
        if (snList == null || snList.isEmpty()) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "设备编码不能为空");
        }

        Integer type = params.getType();
        FshCallType callType = FshCallType.parseValue(type);
        if (callType == null) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "通话类型不存在");
        }
        //获取极光推送注册ID
        List<String> registrationIdList = deviceConfigService.getRegistrationIdList(snList);
        if (registrationIdList == null || registrationIdList.isEmpty()) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "通话对象不存在");
        }

        String strRoomId = params.getStrRoomId();
        if (StringUtils.isBlank(strRoomId)) {
            //以当前时间戳作为房间号
            strRoomId = System.currentTimeMillis() + "";
        }

        //推送发起视频消息
        JPushApi jPushApi = new JPushApi(jpushProps.getAppKey(), jpushProps.getMasterSecret(), jpushProps.getApnsProduction(), JPushPlatform.ANDROID, JPushType.MESSAGE);
        JPushMessage message = new JPushMessage();
        message.setTitle("发起通话");
        message.setContent("发起通话");
        Map<String, String> extras = new HashMap<>();
        extras.put("strRoomId", strRoomId);
        extras.put("type", type.toString());
        message.setExtras(extras);
        jPushApi.pushToDevices(registrationIdList, message);

        return new FshStrRoomIdDTO(strRoomId);
    }
}
